﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Security.Cryptography;
using System.Text;

using Newtonsoft.Json;
using Newtonsoft.Json.Converters;

namespace System.Data.SugarClient
{

	public class SugarRestAction
	{

		public SugarRestAction(
			string restendpoint,
			SugarRestActionParam param)
		{
			this._restEndPoint = restendpoint;
			this._param = param;
		}

		private readonly string _restEndPoint;
		private readonly SugarRestActionParam _param;

		public string RestEndPoint
		{
			get { return _restEndPoint; }
		}

		public SugarRestActionParam Param
		{
			get { return this._param; }
		}

		public SugarRestActionResult Execute()
		{
			WebRequest request = WebRequest.Create(this.RestEndPoint);
			request.Method = "POST";
			request.ContentType = "application/x-www-form-urlencoded";

			JsonSerializer serializer = new JsonSerializer();
			serializer.Converters.Add(new JavaScriptDateTimeConverter());
			serializer.NullValueHandling = NullValueHandling.Ignore;
			using (JsonWriter writer = new JsonTextWriter(new StreamWriter(request.GetRequestStream())))
			{
				serializer.Serialize(writer, Param);
			}

			SugarRestActionResult result = null;
			using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
			{
				Trace.Debug("{0}:HTTP STATUS CODE,{1}", this.RestEndPoint, response.StatusCode);
				using (JsonReader reader = new JsonTextReader(new StreamReader(response.GetResponseStream())))
				{
					try
					{
						object value = serializer.Deserialize(reader);
						result = new SugarRestActionResult(value);
					}
					catch (Exception ex)
					{
						System.Diagnostics.Debug.WriteLine(ex.StackTrace);
					}
				}
				response.Close();
			}
			return result;
		}

		public static SugarRestActionParam CreateActionParam(
			SugarRestActionType type,
			int version,
			params object[] args)
		{
			switch (type)
			{
				// case SugarRestActionType.Login: return new SugarRestActionParam("login", new LoginActionData() { user_name = args[0] as string, password = PasswordDigest(args[1] as string, args[2] as string) });
			}
			throw new NotImplementedException();
		}

		private static string PasswordDigest(string password, string ldapkey)
		{
			return
				Hex((string.IsNullOrEmpty(ldapkey)) ?
					MD5(password) :
					TripleDES(password, ldapkey));
		}

		private static byte[] MD5(string text)
		{
			return System.Security.Cryptography.MD5.Create().ComputeHash(Encoding.Default.GetBytes(text));
		}

		private static byte[] TripleDES(string password, string encryptionkey)
		{
			string userpass = password;

			using (TripleDES des = new TripleDESCryptoServiceProvider())
			{
				des.Mode = CipherMode.CBC;
				des.Key = Encoding.Default.GetBytes(Hex(MD5(encryptionkey)).Substring(0, 24));
				des.IV = Encoding.Default.GetBytes("password");
				des.Padding = PaddingMode.Zeros;

				return
					des.CreateEncryptor().TransformFinalBlock(
						Encoding.Default.GetBytes(userpass),
						0,
						Encoding.Default.GetByteCount(userpass)
						);
			}
		}

		private static string Hex(byte[] bytes)
		{
			StringBuilder s = new StringBuilder();
			foreach (byte b in bytes)
			{
				s.Append(b.ToString("X2", System.Globalization.CultureInfo.InvariantCulture));
			}
			return s.ToString();
		}

	}

	public class SugarRestActionResult
	{

		public SugarRestActionResult(
			object restReturn)
		{
			this._restReturn = restReturn;
		}

		private object _restReturn;

		public object RestReturn
		{
			get { return _restReturn; }
		}

	}

}
